home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Games / Doom / ADoom-0.8 / ADoom_src / wi_stuff.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  34KB  |  1,851 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    Intermission screens.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24. static const char
  25. rcsid[] = "$Id: wi_stuff.c,v 1.7 1997/02/03 22:45:13 b1 Exp $";
  26.  
  27. #include <stdio.h>
  28.  
  29. #include "z_zone.h"
  30.  
  31. #include "m_random.h"
  32. #include "m_swap.h"
  33.  
  34. #include "i_system.h"
  35.  
  36. #include "w_wad.h"
  37.  
  38. #include "g_game.h"
  39.  
  40. #include "r_local.h"
  41. #include "s_sound.h"
  42.  
  43. #include "doomstat.h"
  44.  
  45. // Data.
  46. #include "sounds.h"
  47.  
  48. // Needs access to LFB.
  49. #include "v_video.h"
  50.  
  51. #include "wi_stuff.h"
  52.  
  53. //
  54. // Data needed to add patches to full screen intermission pics.
  55. // Patches are statistics messages, and animations.
  56. // Loads of by-pixel layout and placement, offsets etc.
  57. //
  58.  
  59.  
  60. //
  61. // Different vetween registered DOOM (1994) and
  62. //  Ultimate DOOM - Final edition (retail, 1995?).
  63. // This is supposedly ignored for commercial
  64. //  release (aka DOOM II), which had 34 maps
  65. //  in one episode. So there.
  66. #define NUMEPISODES    4
  67. #define NUMMAPS        9
  68.  
  69.  
  70. // in tics
  71. //U #define PAUSELEN        (TICRATE*2) 
  72. //U #define SCORESTEP        100
  73. //U #define ANIMPERIOD        32
  74. // pixel distance from "(YOU)" to "PLAYER N"
  75. //U #define STARDIST        10 
  76. //U #define WK 1
  77.  
  78.  
  79. // GLOBAL LOCATIONS
  80. #define WI_TITLEY        2
  81. #define WI_SPACINGY            33
  82.  
  83. // SINGPLE-PLAYER STUFF
  84. #define SP_STATSX        50
  85. #define SP_STATSY        50
  86.  
  87. #define SP_TIMEX        16
  88. #define SP_TIMEY        (SCREENHEIGHT-32)
  89.  
  90.  
  91. // NET GAME STUFF
  92. #define NG_STATSY        50
  93. #define NG_STATSX        (32 + SHORT(star->width)/2 + 32*!dofrags)
  94.  
  95. #define NG_SPACINGX            64
  96.  
  97.  
  98. // DEATHMATCH STUFF
  99. #define DM_MATRIXX        42
  100. #define DM_MATRIXY        68
  101.  
  102. #define DM_SPACINGX        40
  103.  
  104. #define DM_TOTALSX        269
  105.  
  106. #define DM_KILLERSX        10
  107. #define DM_KILLERSY        100
  108. #define DM_VICTIMSX            5
  109. #define DM_VICTIMSY        50
  110.  
  111.  
  112.  
  113.  
  114. typedef enum
  115. {
  116.     ANIM_ALWAYS,
  117.     ANIM_RANDOM,
  118.     ANIM_LEVEL
  119.  
  120. } animenum_t;
  121.  
  122. typedef struct
  123. {
  124.     int        x;
  125.     int        y;
  126.     
  127. } point_t;
  128.  
  129.  
  130. //
  131. // Animation.
  132. // There is another anim_t used in p_spec.
  133. //
  134. typedef struct
  135. {
  136.     animenum_t    type;
  137.  
  138.     // period in tics between animations
  139.     int        period;
  140.  
  141.     // number of animation frames
  142.     int        nanims;
  143.  
  144.     // location of animation
  145.     point_t    loc;
  146.  
  147.     // ALWAYS: n/a,
  148.     // RANDOM: period deviation (<256),
  149.     // LEVEL: level
  150.     int        data1;
  151.  
  152.     // ALWAYS: n/a,
  153.     // RANDOM: random base period,
  154.     // LEVEL: n/a
  155.     int        data2; 
  156.  
  157.     // actual graphics for frames of animations
  158.     patch_t*    p[3]; 
  159.  
  160.     // following must be initialized to zero before use!
  161.  
  162.     // next value of bcnt (used in conjunction with period)
  163.     int        nexttic;
  164.  
  165.     // last drawn animation frame
  166.     int        lastdrawn;
  167.  
  168.     // next frame number to animate
  169.     int        ctr;
  170.     
  171.     // used by RANDOM and LEVEL when animating
  172.     int        state;  
  173.  
  174. } anim_t;
  175.  
  176.  
  177. static point_t lnodes[NUMEPISODES][NUMMAPS] =
  178. {
  179.     // Episode 0 World Map
  180.     {
  181.     { 185, 164 },    // location of level 0 (CJ)
  182.     { 148, 143 },    // location of level 1 (CJ)
  183.     { 69, 122 },    // location of level 2 (CJ)
  184.     { 209, 102 },    // location of level 3 (CJ)
  185.     { 116, 89 },    // location of level 4 (CJ)
  186.     { 166, 55 },    // location of level 5 (CJ)
  187.     { 71, 56 },    // location of level 6 (CJ)
  188.     { 135, 29 },    // location of level 7 (CJ)
  189.     { 71, 24 }    // location of level 8 (CJ)
  190.     },
  191.  
  192.     // Episode 1 World Map should go here
  193.     {
  194.     { 254, 25 },    // location of level 0 (CJ)
  195.     { 97, 50 },    // location of level 1 (CJ)
  196.     { 188, 64 },    // location of level 2 (CJ)
  197.     { 128, 78 },    // location of level 3 (CJ)
  198.     { 214, 92 },    // location of level 4 (CJ)
  199.     { 133, 130 },    // location of level 5 (CJ)
  200.     { 208, 136 },    // location of level 6 (CJ)
  201.     { 148, 140 },    // location of level 7 (CJ)
  202.     { 235, 158 }    // location of level 8 (CJ)
  203.     },
  204.  
  205.     // Episode 2 World Map should go here
  206.     {
  207.     { 156, 168 },    // location of level 0 (CJ)
  208.     { 48, 154 },    // location of level 1 (CJ)
  209.     { 174, 95 },    // location of level 2 (CJ)
  210.     { 265, 75 },    // location of level 3 (CJ)
  211.     { 130, 48 },    // location of level 4 (CJ)
  212.     { 279, 23 },    // location of level 5 (CJ)
  213.     { 198, 48 },    // location of level 6 (CJ)
  214.     { 140, 25 },    // location of level 7 (CJ)
  215.     { 281, 136 }    // location of level 8 (CJ)
  216.     }
  217.  
  218. };
  219.  
  220.  
  221. //
  222. // Animation locations for episode 0 (1).
  223. // Using patches saves a lot of space,
  224. //  as they replace 320x200 full screen frames.
  225. //
  226. static anim_t epsd0animinfo[] =
  227. {
  228.     { ANIM_ALWAYS, TICRATE/3, 3, { 224, 104 } },
  229.     { ANIM_ALWAYS, TICRATE/3, 3, { 184, 160 } },
  230.     { ANIM_ALWAYS, TICRATE/3, 3, { 112, 136 } },
  231.     { ANIM_ALWAYS, TICRATE/3, 3, { 72, 112 } },
  232.     { ANIM_ALWAYS, TICRATE/3, 3, { 88, 96 } },
  233.     { ANIM_ALWAYS, TICRATE/3, 3, { 64, 48 } },
  234.     { ANIM_ALWAYS, TICRATE/3, 3, { 192, 40 } },
  235.     { ANIM_ALWAYS, TICRATE/3, 3, { 136, 16 } },
  236.     { ANIM_ALWAYS, TICRATE/3, 3, { 80, 16 } },
  237.     { ANIM_ALWAYS, TICRATE/3, 3, { 64, 24 } }
  238. };
  239.  
  240. static anim_t epsd1animinfo[] =
  241. {
  242.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 1 },
  243.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 2 },
  244.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 3 },
  245.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 4 },
  246.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 5 },
  247.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 6 },
  248.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 7 },
  249.     { ANIM_LEVEL, TICRATE/3, 3, { 192, 144 }, 8 },
  250.     { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 8 }
  251. };
  252.  
  253. static anim_t epsd2animinfo[] =
  254. {
  255.     { ANIM_ALWAYS, TICRATE/3, 3, { 104, 168 } },
  256.     { ANIM_ALWAYS, TICRATE/3, 3, { 40, 136 } },
  257.     { ANIM_ALWAYS, TICRATE/3, 3, { 160, 96 } },
  258.     { ANIM_ALWAYS, TICRATE/3, 3, { 104, 80 } },
  259.     { ANIM_ALWAYS, TICRATE/3, 3, { 120, 32 } },
  260.     { ANIM_ALWAYS, TICRATE/4, 3, { 40, 0 } }
  261. };
  262.  
  263. static int NUMANIMS[NUMEPISODES] =
  264. {
  265.     sizeof(epsd0animinfo)/sizeof(anim_t),
  266.     sizeof(epsd1animinfo)/sizeof(anim_t),
  267.     sizeof(epsd2animinfo)/sizeof(anim_t)
  268. };
  269.  
  270. static anim_t *anims[NUMEPISODES] =
  271. {
  272.     epsd0animinfo,
  273.     epsd1animinfo,
  274.     epsd2animinfo
  275. };
  276.  
  277.  
  278. //
  279. // GENERAL DATA
  280. //
  281.  
  282. //
  283. // Locally used stuff.
  284. //
  285. #define FB 0
  286.  
  287.  
  288. // States for single-player
  289. #define SP_KILLS        0
  290. #define SP_ITEMS        2
  291. #define SP_SECRET        4
  292. #define SP_FRAGS        6 
  293. #define SP_TIME            8 
  294. #define SP_PAR            ST_TIME
  295.  
  296. #define SP_PAUSE        1
  297.  
  298. // in seconds
  299. #define SHOWNEXTLOCDELAY    4
  300. //#define SHOWLASTLOCDELAY    SHOWNEXTLOCDELAY
  301.  
  302.  
  303. // used to accelerate or skip a stage
  304. static int        acceleratestage;
  305.  
  306. // wbs->pnum
  307. static int        me;
  308.  
  309.  // specifies current state
  310. static stateenum_t    state;
  311.  
  312. // contains information passed into intermission
  313. static wbstartstruct_t*    wbs;
  314.  
  315. static wbplayerstruct_t* plrs;  // wbs->plyr[]
  316.  
  317. // used for general timing
  318. static int         cnt;  
  319.  
  320. // used for timing of background animation
  321. static int         bcnt;
  322.  
  323. // signals to refresh everything for one frame
  324. static int         firstrefresh; 
  325.  
  326. static int        cnt_kills[MAXPLAYERS];
  327. static int        cnt_items[MAXPLAYERS];
  328. static int        cnt_secret[MAXPLAYERS];
  329. static int        cnt_time;
  330. static int        cnt_par;
  331. static int        cnt_pause;
  332.  
  333. // # of commercial levels
  334. static int        NUMCMAPS; 
  335.  
  336.  
  337. //
  338. //    GRAPHICS
  339. //
  340.  
  341. // background (map of levels).
  342. static patch_t*        bg;
  343.  
  344. // You Are Here graphic
  345. static patch_t*        yah[2]; 
  346.  
  347. // splat
  348. static patch_t*        splat;
  349.  
  350. // %, : graphics
  351. static patch_t*        percent;
  352. static patch_t*        colon;
  353.  
  354. // 0-9 graphic
  355. static patch_t*        num[10];
  356.  
  357. // minus sign
  358. static patch_t*        wiminus;
  359.  
  360. // "Finished!" graphics
  361. static patch_t*        finished;
  362.  
  363. // "Entering" graphic
  364. static patch_t*        entering; 
  365.  
  366. // "secret"
  367. static patch_t*        sp_secret;
  368.  
  369.  // "Kills", "Scrt", "Items", "Frags"
  370. static patch_t*        kills;
  371. static patch_t*        secret;
  372. static patch_t*        items;
  373. static patch_t*        frags;
  374.  
  375. // Time sucks.
  376. static patch_t*        time;
  377. static patch_t*        par;
  378. static patch_t*        sucks;
  379.  
  380. // "killers", "victims"
  381. static patch_t*        killers;
  382. static patch_t*        victims; 
  383.  
  384. // "Total", your face, your dead face
  385. static patch_t*        total;
  386. static patch_t*        star;
  387. static patch_t*        bstar;
  388.  
  389. // "red P[1..MAXPLAYERS]"
  390. static patch_t*        p[MAXPLAYERS];
  391.  
  392. // "gray P[1..MAXPLAYERS]"
  393. static patch_t*        bp[MAXPLAYERS];
  394.  
  395.  // Name graphics of each level (centered)
  396. static patch_t**    lnames;
  397.  
  398. //
  399. // CODE
  400. //
  401.  
  402. // slam background
  403. // UNUSED static unsigned char *background=0;
  404.  
  405.  
  406. void WI_slamBackground(void)
  407. {
  408.     memcpy(screens[0], screens[1], SCREENWIDTH * SCREENHEIGHT);
  409.     V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  410. }
  411.  
  412. // The ticker is used to detect keys
  413. //  because of timing issues in netgames.
  414. boolean WI_Responder(event_t* ev)
  415. {
  416.     return false;
  417. }
  418.  
  419.  
  420. // Draws "<Levelname> Finished!"
  421. void WI_drawLF(void)
  422. {
  423.     int y = WI_TITLEY;
  424.  
  425.     // draw <LevelName> 
  426.     V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->last]->width))/2,
  427.         y, FB, lnames[wbs->last]);
  428.  
  429.     // draw "Finished!"
  430.     y += (5*SHORT(lnames[wbs->last]->height))/4;
  431.     
  432.     V_DrawPatch((SCREENWIDTH - SHORT(finished->width))/2,
  433.         y, FB, finished);
  434. }
  435.  
  436.  
  437.  
  438. // Draws "Entering <LevelName>"
  439. void WI_drawEL(void)
  440. {
  441.     int y = WI_TITLEY;
  442.  
  443.     // draw "Entering"
  444.     V_DrawPatch((SCREENWIDTH - SHORT(entering->width))/2,
  445.         y, FB, entering);
  446.  
  447.     // draw level
  448.     y += (5*SHORT(lnames[wbs->next]->height))/4;
  449.  
  450.     V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->next]->width))/2,
  451.         y, FB, lnames[wbs->next]);
  452.  
  453. }
  454.  
  455. void
  456. WI_drawOnLnode
  457. ( int        n,
  458.   patch_t*    c[] )
  459. {
  460.  
  461.     int        i;
  462.     int        left;
  463.     int        top;
  464.     int        right;
  465.     int        bottom;
  466.     boolean    fits = false;
  467.  
  468.     i = 0;
  469.     do
  470.     {
  471.     left = lnodes[wbs->epsd][n].x - SHORT(c[i]->leftoffset);
  472.     top = lnodes[wbs->epsd][n].y - SHORT(c[i]->topoffset);
  473.     right = left + SHORT(c[i]->width);
  474.     bottom = top + SHORT(c[i]->height);
  475.  
  476.     if (left >= 0
  477.         && right < SCREENWIDTH
  478.         && top >= 0
  479.         && bottom < SCREENHEIGHT)
  480.     {
  481.         fits = true;
  482.     }
  483.     else
  484.     {
  485.         i++;
  486.     }
  487.     } while (!fits && i!=2);
  488.  
  489.     if (fits && i<2)
  490.     {
  491.     V_DrawPatch(lnodes[wbs->epsd][n].x, lnodes[wbs->epsd][n].y,
  492.             FB, c[i]);
  493.     }
  494.     else
  495.     {
  496.     // DEBUG
  497.     printf("Could not place patch on level %d", n+1); 
  498.     }
  499. }
  500.  
  501.  
  502.  
  503. void WI_initAnimatedBack(void)
  504. {
  505.     int        i;
  506.     anim_t*    a;
  507.  
  508.     if (gamemode == commercial)
  509.     return;
  510.  
  511.     if (wbs->epsd > 2)
  512.     return;
  513.  
  514.     for (i=0;i<NUMANIMS[wbs->epsd];i++)
  515.     {
  516.     a = &anims[wbs->epsd][i];
  517.  
  518.     // init variables
  519.     a->ctr = -1;
  520.  
  521.     // specify the next time to draw it
  522.     if (a->type == ANIM_ALWAYS)
  523.         a->nexttic = bcnt + 1 + (M_Random()%a->period);
  524.     else if (a->type == ANIM_RANDOM)
  525.         a->nexttic = bcnt + 1 + a->data2+(M_Random()%a->data1);
  526.     else if (a->type == ANIM_LEVEL)
  527.         a->nexttic = bcnt + 1;
  528.     }
  529.  
  530. }
  531.  
  532. void WI_updateAnimatedBack(void)
  533. {
  534.     int        i;
  535.     anim_t*    a;
  536.  
  537.     if (gamemode == commercial)
  538.     return;
  539.  
  540.     if (wbs->epsd > 2)
  541.     return;
  542.  
  543.     for (i=0;i<NUMANIMS[wbs->epsd];i++)
  544.     {
  545.     a = &anims[wbs->epsd][i];
  546.  
  547.     if (bcnt == a->nexttic)
  548.     {
  549.         switch (a->type)
  550.         {
  551.           case ANIM_ALWAYS:
  552.         if (++a->ctr >= a->nanims) a->ctr = 0;
  553.         a->nexttic = bcnt + a->period;
  554.         break;
  555.  
  556.           case ANIM_RANDOM:
  557.         a->ctr++;
  558.         if (a->ctr == a->nanims)
  559.         {
  560.             a->ctr = -1;
  561.             a->nexttic = bcnt+a->data2+(M_Random()%a->data1);
  562.         }
  563.         else a->nexttic = bcnt + a->period;
  564.         break;
  565.         
  566.           case ANIM_LEVEL:
  567.         // gawd-awful hack for level anims
  568.         if (!(state == StatCount && i == 7)
  569.             && wbs->next == a->data1)
  570.         {
  571.             a->ctr++;
  572.             if (a->ctr == a->nanims) a->ctr--;
  573.             a->nexttic = bcnt + a->period;
  574.         }
  575.         break;
  576.         }
  577.     }
  578.  
  579.     }
  580.  
  581. }
  582.  
  583. void WI_drawAnimatedBack(void)
  584. {
  585.     int            i;
  586.     anim_t*        a;
  587.  
  588.     if (commercial)
  589.     return;
  590.  
  591.     if (wbs->epsd > 2)
  592.     return;
  593.  
  594.     for (i=0 ; i<NUMANIMS[wbs->epsd] ; i++)
  595.     {
  596.     a = &anims[wbs->epsd][i];
  597.  
  598.     if (a->ctr >= 0)
  599.         V_DrawPatch(a->loc.x, a->loc.y, FB, a->p[a->ctr]);
  600.     }
  601.  
  602. }
  603.  
  604. //
  605. // Draws a number.
  606. // If digits > 0, then use that many digits minimum,
  607. //  otherwise only use as many as necessary.
  608. // Returns new x position.
  609. //
  610.  
  611. int
  612. WI_drawNum
  613. ( int        x,
  614.   int        y,
  615.   int        n,
  616.   int        digits )
  617. {
  618.  
  619.     int        fontwidth = SHORT(num[0]->width);
  620.     int        neg;
  621.     int        temp;
  622.  
  623.     if (digits < 0)
  624.     {
  625.     if (!n)
  626.     {
  627.         // make variable-length zeros 1 digit long
  628.         digits = 1;
  629.     }
  630.     else
  631.     {
  632.         // figure out # of digits in #
  633.         digits = 0;
  634.         temp = n;
  635.  
  636.         while (temp)
  637.         {
  638.         temp /= 10;
  639.         digits++;
  640.         }
  641.     }
  642.     }
  643.  
  644.     neg = n < 0;
  645.     if (neg)
  646.     n = -n;
  647.  
  648.     // if non-number, do not draw it
  649.     if (n == 1994)
  650.     return 0;
  651.  
  652.     // draw the new number
  653.     while (digits--)
  654.     {
  655.     x -= fontwidth;
  656.     V_DrawPatch(x, y, FB, num[ n % 10 ]);
  657.     n /= 10;
  658.     }
  659.  
  660.     // draw a minus sign if necessary
  661.     if (neg)
  662.     V_DrawPatch(x-=8, y, FB, wiminus);
  663.  
  664.     return x;
  665.  
  666. }
  667.  
  668. void
  669. WI_drawPercent
  670. ( int        x,
  671.   int        y,
  672.   int        p )
  673. {
  674.     if (p < 0)
  675.     return;
  676.  
  677.     V_DrawPatch(x, y, FB, percent);
  678.     WI_drawNum(x, y, p, -1);
  679. }
  680.  
  681.  
  682.  
  683. //
  684. // Display level completion time and par,
  685. //  or "sucks" message if overflow.
  686. //
  687. void
  688. WI_drawTime
  689. ( int        x,
  690.   int        y,
  691.   int        t )
  692. {
  693.  
  694.     int        div;
  695.     int        n;
  696.  
  697.     if (t<0)
  698.     return;
  699.  
  700.     if (t <= 61*59)
  701.     {
  702.     div = 1;
  703.  
  704.     do
  705.     {
  706.         n = (t / div) % 60;
  707.         x = WI_drawNum(x, y, n, 2) - SHORT(colon->width);
  708.         div *= 60;
  709.  
  710.         // draw
  711.         if (div==60 || t / div)
  712.         V_DrawPatch(x, y, FB, colon);
  713.         
  714.     } while (t / div);
  715.     }
  716.     else
  717.     {
  718.     // "sucks"
  719.     V_DrawPatch(x - SHORT(sucks->width), y, FB, sucks); 
  720.     }
  721. }
  722.  
  723.  
  724. void WI_End(void)
  725. {
  726.     void WI_unloadData(void);
  727.     WI_unloadData();
  728. }
  729.  
  730. void WI_initNoState(void)
  731. {
  732.     state = NoState;
  733.     acceleratestage = 0;
  734.     cnt = 10;
  735. }
  736.  
  737. void WI_updateNoState(void) {
  738.  
  739.     WI_updateAnimatedBack();
  740.  
  741.     if (!--cnt)
  742.     {
  743.     WI_End();
  744.     G_WorldDone();
  745.     }
  746.  
  747. }
  748.  
  749. static boolean        snl_pointeron = false;
  750.  
  751.  
  752. void WI_initShowNextLoc(void)
  753. {
  754.     state = ShowNextLoc;
  755.     acceleratestage = 0;
  756.     cnt = SHOWNEXTLOCDELAY * TICRATE;
  757.  
  758.     WI_initAnimatedBack();
  759. }
  760.  
  761. void WI_updateShowNextLoc(void)
  762. {
  763.     WI_updateAnimatedBack();
  764.  
  765.     if (!--cnt || acceleratestage)
  766.     WI_initNoState();
  767.     else
  768.     snl_pointeron = (cnt & 31) < 20;
  769. }
  770.  
  771. void WI_drawShowNextLoc(void)
  772. {
  773.  
  774.     int        i;
  775.     int        last;
  776.  
  777.     WI_slamBackground();
  778.  
  779.     // draw animated background
  780.     WI_drawAnimatedBack(); 
  781.  
  782.     if ( gamemode != commercial)
  783.     {
  784.       if (wbs->epsd > 2)
  785.     {
  786.         WI_drawEL();
  787.         return;
  788.     }
  789.     
  790.     last = (wbs->last == 8) ? wbs->next - 1 : wbs->last;
  791.  
  792.     // draw a splat on taken cities.
  793.     for (i=0 ; i<=last ; i++)
  794.         WI_drawOnLnode(i, &splat);
  795.  
  796.     // splat the secret level?
  797.     if (wbs->didsecret)
  798.         WI_drawOnLnode(8, &splat);
  799.  
  800.     // draw flashing ptr
  801.     if (snl_pointeron)
  802.         WI_drawOnLnode(wbs->next, yah); 
  803.     }
  804.  
  805.     // draws which level you are entering..
  806.     if ( (gamemode != commercial)
  807.      || wbs->next != 30)
  808.     WI_drawEL();  
  809.  
  810. }
  811.  
  812. void WI_drawNoState(void)
  813. {
  814.     snl_pointeron = true;
  815.     WI_drawShowNextLoc();
  816. }
  817.  
  818. int WI_fragSum(int playernum)
  819. {
  820.     int        i;
  821.     int        frags = 0;
  822.     
  823.     for (i=0 ; i<MAXPLAYERS ; i++)
  824.     {
  825.     if (playeringame[i]
  826.         && i!=playernum)
  827.     {
  828.         frags += plrs[playernum].frags[i];
  829.     }
  830.     }
  831.  
  832.     
  833.     // JDC hack - negative frags.
  834.     frags -= plrs[playernum].frags[playernum];
  835.     // UNUSED if (frags < 0)
  836.     //     frags = 0;
  837.  
  838.     return frags;
  839. }
  840.  
  841.  
  842.  
  843. static int        dm_state;
  844. static int        dm_frags[MAXPLAYERS][MAXPLAYERS];
  845. static int        dm_totals[MAXPLAYERS];
  846.  
  847.  
  848.  
  849. void WI_initDeathmatchStats(void)
  850. {
  851.  
  852.     int        i;
  853.     int        j;
  854.  
  855.     state = StatCount;
  856.     acceleratestage = 0;
  857.     dm_state = 1;
  858.  
  859.     cnt_pause = TICRATE;
  860.  
  861.     for (i=0 ; i<MAXPLAYERS ; i++)
  862.     {
  863.     if (playeringame[i])
  864.     {
  865.         for (j=0 ; j<MAXPLAYERS ; j++)
  866.         if (playeringame[j])
  867.             dm_frags[i][j] = 0;
  868.  
  869.         dm_totals[i] = 0;
  870.     }
  871.     }
  872.     
  873.     WI_initAnimatedBack();
  874. }
  875.  
  876.  
  877.  
  878. void WI_updateDeathmatchStats(void)
  879. {
  880.  
  881.     int        i;
  882.     int        j;
  883.     
  884.     boolean    stillticking;
  885.  
  886.     WI_updateAnimatedBack();
  887.  
  888.     if (acceleratestage && dm_state != 4)
  889.     {
  890.     acceleratestage = 0;
  891.  
  892.     for (i=0 ; i<MAXPLAYERS ; i++)
  893.     {
  894.         if (playeringame[i])
  895.         {
  896.         for (j=0 ; j<MAXPLAYERS ; j++)
  897.             if (playeringame[j])
  898.             dm_frags[i][j] = plrs[i].frags[j];
  899.  
  900.         dm_totals[i] = WI_fragSum(i);
  901.         }
  902.     }
  903.     
  904.  
  905.     S_StartSound(0, sfx_barexp);
  906.     dm_state = 4;
  907.     }
  908.  
  909.     
  910.     if (dm_state == 2)
  911.     {
  912.     if (!(bcnt&3))
  913.         S_StartSound(0, sfx_pistol);
  914.     
  915.     stillticking = false;
  916.  
  917.     for (i=0 ; i<MAXPLAYERS ; i++)
  918.     {
  919.         if (playeringame[i])
  920.         {
  921.         for (j=0 ; j<MAXPLAYERS ; j++)
  922.         {
  923.             if (playeringame[j]
  924.             && dm_frags[i][j] != plrs[i].frags[j])
  925.             {
  926.             if (plrs[i].frags[j] < 0)
  927.                 dm_frags[i][j]--;
  928.             else
  929.                 dm_frags[i][j]++;
  930.  
  931.             if (dm_frags[i][j] > 99)
  932.                 dm_frags[i][j] = 99;
  933.  
  934.             if (dm_frags[i][j] < -99)
  935.                 dm_frags[i][j] = -99;
  936.             
  937.             stillticking = true;
  938.             }
  939.         }
  940.         dm_totals[i] = WI_fragSum(i);
  941.  
  942.         if (dm_totals[i] > 99)
  943.             dm_totals[i] = 99;
  944.         
  945.         if (dm_totals[i] < -99)
  946.             dm_totals[i] = -99;
  947.         }
  948.         
  949.     }
  950.     if (!stillticking)
  951.     {
  952.         S_StartSound(0, sfx_barexp);
  953.         dm_state++;
  954.     }
  955.  
  956.     }
  957.     else if (dm_state == 4)
  958.     {
  959.     if (acceleratestage)
  960.     {
  961.         S_StartSound(0, sfx_slop);
  962.  
  963.         if ( gamemode == commercial)
  964.         WI_initNoState();
  965.         else
  966.         WI_initShowNextLoc();
  967.     }
  968.     }
  969.     else if (dm_state & 1)
  970.     {
  971.     if (!--cnt_pause)
  972.     {
  973.         dm_state++;
  974.         cnt_pause = TICRATE;
  975.     }
  976.     }
  977. }
  978.  
  979.  
  980.  
  981. void WI_drawDeathmatchStats(void)
  982. {
  983.  
  984.     int        i;
  985.     int        j;
  986.     int        x;
  987.     int        y;
  988.     int        w;
  989.     
  990.     int        lh;    // line height
  991.  
  992.     lh = WI_SPACINGY;
  993.  
  994.     WI_slamBackground();
  995.     
  996.     // draw animated background
  997.     WI_drawAnimatedBack(); 
  998.     WI_drawLF();
  999.  
  1000.     // draw stat titles (top line)
  1001.     V_DrawPatch(DM_TOTALSX-SHORT(total->width)/2,
  1002.         DM_MATRIXY-WI_SPACINGY+10,
  1003.         FB,
  1004.         total);
  1005.     
  1006.     V_DrawPatch(DM_KILLERSX, DM_KILLERSY, FB, killers);
  1007.     V_DrawPatch(DM_VICTIMSX, DM_VICTIMSY, FB, victims);
  1008.  
  1009.     // draw P?
  1010.     x = DM_MATRIXX + DM_SPACINGX;
  1011.     y = DM_MATRIXY;
  1012.  
  1013.     for (i=0 ; i<MAXPLAYERS ; i++)
  1014.     {
  1015.     if (playeringame[i])
  1016.     {
  1017.         V_DrawPatch(x-SHORT(p[i]->width)/2,
  1018.             DM_MATRIXY - WI_SPACINGY,
  1019.             FB,
  1020.             p[i]);
  1021.         
  1022.         V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2,
  1023.             y,
  1024.             FB,
  1025.             p[i]);
  1026.  
  1027.         if (i == me)
  1028.         {
  1029.         V_DrawPatch(x-SHORT(p[i]->width)/2,
  1030.                 DM_MATRIXY - WI_SPACINGY,
  1031.                 FB,
  1032.                 bstar);
  1033.  
  1034.         V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2,
  1035.                 y,
  1036.                 FB,
  1037.                 star);
  1038.         }
  1039.     }
  1040.     else
  1041.     {
  1042.         // V_DrawPatch(x-SHORT(bp[i]->width)/2,
  1043.         //   DM_MATRIXY - WI_SPACINGY, FB, bp[i]);
  1044.         // V_DrawPatch(DM_MATRIXX-SHORT(bp[i]->width)/2,
  1045.         //   y, FB, bp[i]);
  1046.     }
  1047.     x += DM_SPACINGX;
  1048.     y += WI_SPACINGY;
  1049.     }
  1050.  
  1051.     // draw stats
  1052.     y = DM_MATRIXY+10;
  1053.     w = SHORT(num[0]->width);
  1054.  
  1055.     for (i=0 ; i<MAXPLAYERS ; i++)
  1056.     {
  1057.     x = DM_MATRIXX + DM_SPACINGX;
  1058.  
  1059.     if (playeringame[i])
  1060.     {
  1061.         for (j=0 ; j<MAXPLAYERS ; j++)
  1062.         {
  1063.         if (playeringame[j])
  1064.             WI_drawNum(x+w, y, dm_frags[i][j], 2);
  1065.  
  1066.         x += DM_SPACINGX;
  1067.         }
  1068.         WI_drawNum(DM_TOTALSX+w, y, dm_totals[i], 2);
  1069.     }
  1070.     y += WI_SPACINGY;
  1071.     }
  1072. }
  1073.  
  1074. static int    cnt_frags[MAXPLAYERS];
  1075. static int    dofrags;
  1076. static int    ng_state;
  1077.  
  1078. void WI_initNetgameStats(void)
  1079. {
  1080.  
  1081.     int i;
  1082.  
  1083.     state = StatCount;
  1084.     acceleratestage = 0;
  1085.     ng_state = 1;
  1086.  
  1087.     cnt_pause = TICRATE;
  1088.  
  1089.     for (i=0 ; i<MAXPLAYERS ; i++)
  1090.     {
  1091.     if (!playeringame[i])
  1092.         continue;
  1093.  
  1094.     cnt_kills[i] = cnt_items[i] = cnt_secret[i] = cnt_frags[i] = 0;
  1095.  
  1096.     dofrags += WI_fragSum(i);
  1097.     }
  1098.  
  1099.     dofrags = !!dofrags;
  1100.  
  1101.     WI_initAnimatedBack();
  1102. }
  1103.  
  1104.  
  1105.  
  1106. void WI_updateNetgameStats(void)
  1107. {
  1108.  
  1109.     int        i;
  1110.     int        fsum;
  1111.     
  1112.     boolean    stillticking;
  1113.  
  1114.     WI_updateAnimatedBack();
  1115.  
  1116.     if (acceleratestage && ng_state != 10)
  1117.     {
  1118.     acceleratestage = 0;
  1119.  
  1120.     for (i=0 ; i<MAXPLAYERS ; i++)
  1121.     {
  1122.         if (!playeringame[i])
  1123.         continue;
  1124.  
  1125.         cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills;
  1126.         cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems;
  1127.         cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret;
  1128.  
  1129.         if (dofrags)
  1130.         cnt_frags[i] = WI_fragSum(i);
  1131.     }
  1132.     S_StartSound(0, sfx_barexp);
  1133.     ng_state = 10;
  1134.     }
  1135.  
  1136.     if (ng_state == 2)
  1137.     {
  1138.     if (!(bcnt&3))
  1139.         S_StartSound(0, sfx_pistol);
  1140.  
  1141.     stillticking = false;
  1142.  
  1143.     for (i=0 ; i<MAXPLAYERS ; i++)
  1144.     {
  1145.         if (!playeringame[i])
  1146.         continue;
  1147.  
  1148.         cnt_kills[i] += 2;
  1149.  
  1150.         if (cnt_kills[i] >= (plrs[i].skills * 100) / wbs->maxkills)
  1151.         cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills;
  1152.         else
  1153.         stillticking = true;
  1154.     }
  1155.     
  1156.     if (!stillticking)
  1157.     {
  1158.         S_StartSound(0, sfx_barexp);
  1159.         ng_state++;
  1160.     }
  1161.     }
  1162.     else if (ng_state == 4)
  1163.     {
  1164.     if (!(bcnt&3))
  1165.         S_StartSound(0, sfx_pistol);
  1166.  
  1167.     stillticking = false;
  1168.  
  1169.     for (i=0 ; i<MAXPLAYERS ; i++)
  1170.     {
  1171.         if (!playeringame[i])
  1172.         continue;
  1173.  
  1174.         cnt_items[i] += 2;
  1175.         if (cnt_items[i] >= (plrs[i].sitems * 100) / wbs->maxitems)
  1176.         cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems;
  1177.         else
  1178.         stillticking = true;
  1179.     }
  1180.     if (!stillticking)
  1181.     {
  1182.         S_StartSound(0, sfx_barexp);
  1183.         ng_state++;
  1184.     }
  1185.     }
  1186.     else if (ng_state == 6)
  1187.     {
  1188.     if (!(bcnt&3))
  1189.         S_StartSound(0, sfx_pistol);
  1190.  
  1191.     stillticking = false;
  1192.  
  1193.     for (i=0 ; i<MAXPLAYERS ; i++)
  1194.     {
  1195.         if (!playeringame[i])
  1196.         continue;
  1197.  
  1198.         cnt_secret[i] += 2;
  1199.  
  1200.         if (cnt_secret[i] >= (plrs[i].ssecret * 100) / wbs->maxsecret)
  1201.         cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret;
  1202.         else
  1203.         stillticking = true;
  1204.     }
  1205.     
  1206.     if (!stillticking)
  1207.     {
  1208.         S_StartSound(0, sfx_barexp);
  1209.         ng_state += 1 + 2*!dofrags;
  1210.     }
  1211.     }
  1212.     else if (ng_state == 8)
  1213.     {
  1214.     if (!(bcnt&3))
  1215.         S_StartSound(0, sfx_pistol);
  1216.  
  1217.     stillticking = false;
  1218.  
  1219.     for (i=0 ; i<MAXPLAYERS ; i++)
  1220.     {
  1221.         if (!playeringame[i])
  1222.         continue;
  1223.  
  1224.         cnt_frags[i] += 1;
  1225.  
  1226.         if (cnt_frags[i] >= (fsum = WI_fragSum(i)))
  1227.         cnt_frags[i] = fsum;
  1228.         else
  1229.         stillticking = true;
  1230.     }
  1231.     
  1232.     if (!stillticking)
  1233.     {
  1234.         S_StartSound(0, sfx_pldeth);
  1235.         ng_state++;
  1236.     }
  1237.     }
  1238.     else if (ng_state == 10)
  1239.     {
  1240.     if (acceleratestage)
  1241.     {
  1242.         S_StartSound(0, sfx_sgcock);
  1243.         if ( gamemode == commercial )
  1244.         WI_initNoState();
  1245.         else
  1246.         WI_initShowNextLoc();
  1247.     }
  1248.     }
  1249.     else if (ng_state & 1)
  1250.     {
  1251.     if (!--cnt_pause)
  1252.     {
  1253.         ng_state++;
  1254.         cnt_pause = TICRATE;
  1255.     }
  1256.     }
  1257. }
  1258.  
  1259.  
  1260.  
  1261. void WI_drawNetgameStats(void)
  1262. {
  1263.     int        i;
  1264.     int        x;
  1265.     int        y;
  1266.     int        pwidth = SHORT(percent->width);
  1267.  
  1268.     WI_slamBackground();
  1269.     
  1270.     // draw animated background
  1271.     WI_drawAnimatedBack(); 
  1272.  
  1273.     WI_drawLF();
  1274.  
  1275.     // draw stat titles (top line)
  1276.     V_DrawPatch(NG_STATSX+NG_SPACINGX-SHORT(kills->width),
  1277.         NG_STATSY, FB, kills);
  1278.  
  1279.     V_DrawPatch(NG_STATSX+2*NG_SPACINGX-SHORT(items->width),
  1280.         NG_STATSY, FB, items);
  1281.  
  1282.     V_DrawPatch(NG_STATSX+3*NG_SPACINGX-SHORT(secret->width),
  1283.         NG_STATSY, FB, secret);
  1284.     
  1285.     if (dofrags)
  1286.     V_DrawPatch(NG_STATSX+4*NG_SPACINGX-SHORT(frags->width),
  1287.             NG_STATSY, FB, frags);
  1288.  
  1289.     // draw stats
  1290.     y = NG_STATSY + SHORT(kills->height);
  1291.  
  1292.     for (i=0 ; i<MAXPLAYERS ; i++)
  1293.     {
  1294.     if (!playeringame[i])
  1295.         continue;
  1296.  
  1297.     x = NG_STATSX;
  1298.     V_DrawPatch(x-SHORT(p[i]->width), y, FB, p[i]);
  1299.  
  1300.     if (i == me)
  1301.         V_DrawPatch(x-SHORT(p[i]->width), y, FB, star);
  1302.  
  1303.     x += NG_SPACINGX;
  1304.     WI_drawPercent(x-pwidth, y+10, cnt_kills[i]);    x += NG_SPACINGX;
  1305.     WI_drawPercent(x-pwidth, y+10, cnt_items[i]);    x += NG_SPACINGX;
  1306.     WI_drawPercent(x-pwidth, y+10, cnt_secret[i]);    x += NG_SPACINGX;
  1307.  
  1308.     if (dofrags)
  1309.         WI_drawNum(x, y+10, cnt_frags[i], -1);
  1310.  
  1311.     y += WI_SPACINGY;
  1312.     }
  1313.  
  1314. }
  1315.  
  1316. static int    sp_state;
  1317.  
  1318. void WI_initStats(void)
  1319. {
  1320.     state = StatCount;
  1321.     acceleratestage = 0;
  1322.     sp_state = 1;
  1323.     cnt_kills[0] = cnt_items[0] = cnt_secret[0] = -1;
  1324.     cnt_time = cnt_par = -1;
  1325.     cnt_pause = TICRATE;
  1326.  
  1327.     WI_initAnimatedBack();
  1328. }
  1329.  
  1330. void WI_updateStats(void)
  1331. {
  1332.  
  1333.     WI_updateAnimatedBack();
  1334.  
  1335.     if (acceleratestage && sp_state != 10)
  1336.     {
  1337.     acceleratestage = 0;
  1338.     cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills;
  1339.     cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems;
  1340.     cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret;
  1341.     cnt_time = plrs[me].stime / TICRATE;
  1342.     cnt_par = wbs->partime / TICRATE;
  1343.     S_StartSound(0, sfx_barexp);
  1344.     sp_state = 10;
  1345.     }
  1346.  
  1347.     if (sp_state == 2)
  1348.     {
  1349.     cnt_kills[0] += 2;
  1350.  
  1351.     if (!(bcnt&3))
  1352.         S_StartSound(0, sfx_pistol);
  1353.  
  1354.     if (cnt_kills[0] >= (plrs[me].skills * 100) / wbs->maxkills)
  1355.     {
  1356.         cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills;
  1357.         S_StartSound(0, sfx_barexp);
  1358.         sp_state++;
  1359.     }
  1360.     }
  1361.     else if (sp_state == 4)
  1362.     {
  1363.     cnt_items[0] += 2;
  1364.  
  1365.     if (!(bcnt&3))
  1366.         S_StartSound(0, sfx_pistol);
  1367.  
  1368.     if (cnt_items[0] >= (plrs[me].sitems * 100) / wbs->maxitems)
  1369.     {
  1370.         cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems;
  1371.         S_StartSound(0, sfx_barexp);
  1372.         sp_state++;
  1373.     }
  1374.     }
  1375.     else if (sp_state == 6)
  1376.     {
  1377.     cnt_secret[0] += 2;
  1378.  
  1379.     if (!(bcnt&3))
  1380.         S_StartSound(0, sfx_pistol);
  1381.  
  1382.     if (cnt_secret[0] >= (plrs[me].ssecret * 100) / wbs->maxsecret)
  1383.     {
  1384.         cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret;
  1385.         S_StartSound(0, sfx_barexp);
  1386.         sp_state++;
  1387.     }
  1388.     }
  1389.  
  1390.     else if (sp_state == 8)
  1391.     {
  1392.     if (!(bcnt&3))
  1393.         S_StartSound(0, sfx_pistol);
  1394.  
  1395.     cnt_time += 3;
  1396.  
  1397.     if (cnt_time >= plrs[me].stime / TICRATE)
  1398.         cnt_time = plrs[me].stime / TICRATE;
  1399.  
  1400.     cnt_par += 3;
  1401.  
  1402.     if (cnt_par >= wbs->partime / TICRATE)
  1403.     {
  1404.         cnt_par = wbs->partime / TICRATE;
  1405.  
  1406.         if (cnt_time >= plrs[me].stime / TICRATE)
  1407.         {
  1408.         S_StartSound(0, sfx_barexp);
  1409.         sp_state++;
  1410.         }
  1411.     }
  1412.     }
  1413.     else if (sp_state == 10)
  1414.     {
  1415.     if (acceleratestage)
  1416.     {
  1417.         S_StartSound(0, sfx_sgcock);
  1418.  
  1419.         if (gamemode == commercial)
  1420.         WI_initNoState();
  1421.         else
  1422.         WI_initShowNextLoc();
  1423.     }
  1424.     }
  1425.     else if (sp_state & 1)
  1426.     {
  1427.     if (!--cnt_pause)
  1428.     {
  1429.         sp_state++;
  1430.         cnt_pause = TICRATE;
  1431.     }
  1432.     }
  1433.  
  1434. }
  1435.  
  1436. void WI_drawStats(void)
  1437. {
  1438.     // line height
  1439.     int lh;    
  1440.  
  1441.     lh = (3*SHORT(num[0]->height))/2;
  1442.  
  1443.     WI_slamBackground();
  1444.  
  1445.     // draw animated background
  1446.     WI_drawAnimatedBack();
  1447.     
  1448.     WI_drawLF();
  1449.  
  1450.     V_DrawPatch(SP_STATSX, SP_STATSY, FB, kills);
  1451.     WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]);
  1452.  
  1453.     V_DrawPatch(SP_STATSX, SP_STATSY+lh, FB, items);
  1454.     WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]);
  1455.  
  1456.     V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, FB, sp_secret);
  1457.     WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]);
  1458.  
  1459.     V_DrawPatch(SP_TIMEX, SP_TIMEY, FB, time);
  1460.     WI_drawTime(SCREENWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time);
  1461.  
  1462.     if (wbs->epsd < 3)
  1463.     {
  1464.     V_DrawPatch(SCREENWIDTH/2 + SP_TIMEX, SP_TIMEY, FB, par);
  1465.     WI_drawTime(SCREENWIDTH - SP_TIMEX, SP_TIMEY, cnt_par);
  1466.     }
  1467.  
  1468. }
  1469.  
  1470. void WI_checkForAccelerate(void)
  1471. {
  1472.     int   i;
  1473.     player_t  *player;
  1474.  
  1475.     // check for button presses to skip delays
  1476.     for (i=0, player = players ; i<MAXPLAYERS ; i++, player++)
  1477.     {
  1478.     if (playeringame[i])
  1479.     {
  1480.         if (player->cmd.buttons & BT_ATTACK)
  1481.         {
  1482.         if (!player->attackdown)
  1483.             acceleratestage = 1;
  1484.         player->attackdown = true;
  1485.         }
  1486.         else
  1487.         player->attackdown = false;
  1488.         if (player->cmd.buttons & BT_USE)
  1489.         {
  1490.         if (!player->usedown)
  1491.             acceleratestage = 1;
  1492.         player->usedown = true;
  1493.         }
  1494.         else
  1495.         player->usedown = false;
  1496.     }
  1497.     }
  1498. }
  1499.  
  1500.  
  1501.  
  1502. // Updates stuff each tick
  1503. void WI_Ticker(void)
  1504. {
  1505.     // counter for general background animation
  1506.     bcnt++;  
  1507.  
  1508.     if (bcnt == 1)
  1509.     {
  1510.     // intermission music
  1511.       if ( gamemode == commercial )
  1512.       S_ChangeMusic(mus_dm2int, true);
  1513.     else
  1514.       S_ChangeMusic(mus_inter, true); 
  1515.     }
  1516.  
  1517.     WI_checkForAccelerate();
  1518.  
  1519.     switch (state)
  1520.     {
  1521.       case StatCount:
  1522.     if (deathmatch) WI_updateDeathmatchStats();
  1523.     else if (netgame) WI_updateNetgameStats();
  1524.     else WI_updateStats();
  1525.     break;
  1526.     
  1527.       case ShowNextLoc:
  1528.     WI_updateShowNextLoc();
  1529.     break;
  1530.     
  1531.       case NoState:
  1532.     WI_updateNoState();
  1533.     break;
  1534.     }
  1535.  
  1536. }
  1537.  
  1538. void WI_loadData(void)
  1539. {
  1540.     int        i;
  1541.     int        j;
  1542.     char    name[9];
  1543.     anim_t*    a;
  1544.  
  1545.     if (gamemode == commercial)
  1546.     strcpy(name, "INTERPIC");
  1547.     else 
  1548.     sprintf(name, "WIMAP%d", wbs->epsd);
  1549.     
  1550.     if ( gamemode == retail )
  1551.     {
  1552.       if (wbs->epsd == 3)
  1553.     strcpy(name,"INTERPIC");
  1554.     }
  1555.  
  1556.     // background
  1557.     bg = W_CacheLumpName(name, PU_CACHE);    
  1558.     V_DrawPatch(0, 0, 1, bg);
  1559.  
  1560.  
  1561.     // UNUSED unsigned char *pic = screens[1];
  1562.     // if (gamemode == commercial)
  1563.     // {
  1564.     // darken the background image
  1565.     // while (pic != screens[1] + SCREENHEIGHT*SCREENWIDTH)
  1566.     // {
  1567.     //   *pic = colormaps[256*25 + *pic];
  1568.     //   pic++;
  1569.     // }
  1570.     //}
  1571.  
  1572.     if (gamemode == commercial)
  1573.     {
  1574.     NUMCMAPS = 32;                                
  1575.     lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMCMAPS,
  1576.                        PU_STATIC, 0);
  1577.     for (i=0 ; i<NUMCMAPS ; i++)
  1578.     {                                
  1579.         sprintf(name, "CWILV%2.2d", i);
  1580.         lnames[i] = W_CacheLumpName(name, PU_STATIC);
  1581.     }                    
  1582.     }
  1583.     else
  1584.     {
  1585.     lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMMAPS,
  1586.                        PU_STATIC, 0);
  1587.     for (i=0 ; i<NUMMAPS ; i++)
  1588.     {
  1589.         sprintf(name, "WILV%d%d", wbs->epsd, i);
  1590.         lnames[i] = W_CacheLumpName(name, PU_STATIC);
  1591.     }
  1592.  
  1593.     // you are here
  1594.     yah[0] = W_CacheLumpName("WIURH0", PU_STATIC);
  1595.  
  1596.     // you are here (alt.)
  1597.     yah[1] = W_CacheLumpName("WIURH1", PU_STATIC);
  1598.  
  1599.     // splat
  1600.     splat = W_CacheLumpName("WISPLAT", PU_STATIC); 
  1601.     
  1602.     if (wbs->epsd < 3)
  1603.     {
  1604.         for (j=0;j<NUMANIMS[wbs->epsd];j++)
  1605.         {
  1606.         a = &anims[wbs->epsd][j];
  1607.         for (i=0;i<a->nanims;i++)
  1608.         {
  1609.             // MONDO HACK!
  1610.             if (wbs->epsd != 1 || j != 8) 
  1611.             {
  1612.             // animations
  1613.             sprintf(name, "WIA%d%.2d%.2d", wbs->epsd, j, i);  
  1614.             a->p[i] = W_CacheLumpName(name, PU_STATIC);
  1615.             }
  1616.             else
  1617.             {
  1618.             // HACK ALERT!
  1619.             a->p[i] = anims[1][4].p[i]; 
  1620.             }
  1621.         }
  1622.         }
  1623.     }
  1624.     }
  1625.  
  1626.     // More hacks on minus sign.
  1627.     wiminus = W_CacheLumpName("WIMINUS", PU_STATIC); 
  1628.  
  1629.     for (i=0;i<10;i++)
  1630.     {
  1631.      // numbers 0-9
  1632.     sprintf(name, "WINUM%d", i);     
  1633.     num[i] = W_CacheLumpName(name, PU_STATIC);
  1634.     }
  1635.  
  1636.     // percent sign
  1637.     percent = W_CacheLumpName("WIPCNT", PU_STATIC);
  1638.  
  1639.     // "finished"
  1640.     finished = W_CacheLumpName("WIF", PU_STATIC);
  1641.  
  1642.     // "entering"
  1643.     entering = W_CacheLumpName("WIENTER", PU_STATIC);
  1644.  
  1645.     // "kills"
  1646.     kills = W_CacheLumpName("WIOSTK", PU_STATIC);   
  1647.  
  1648.     // "scrt"
  1649.     secret = W_CacheLumpName("WIOSTS", PU_STATIC);
  1650.  
  1651.      // "secret"
  1652.     sp_secret = W_CacheLumpName("WISCRT2", PU_STATIC);
  1653.  
  1654.     // Yuck. 
  1655.     if (french)
  1656.     {
  1657.     // "items"
  1658.     if (netgame && !deathmatch)
  1659.         items = W_CacheLumpName("WIOBJ", PU_STATIC);    
  1660.       else
  1661.         items = W_CacheLumpName("WIOSTI", PU_STATIC);
  1662.     } else
  1663.     items = W_CacheLumpName("WIOSTI", PU_STATIC);
  1664.  
  1665.     // "frgs"
  1666.     frags = W_CacheLumpName("WIFRGS", PU_STATIC);    
  1667.  
  1668.     // ":"
  1669.     colon = W_CacheLumpName("WICOLON", PU_STATIC); 
  1670.  
  1671.     // "time"
  1672.     time = W_CacheLumpName("WITIME", PU_STATIC);   
  1673.  
  1674.     // "sucks"
  1675.     sucks = W_CacheLumpName("WISUCKS", PU_STATIC);  
  1676.  
  1677.     // "par"
  1678.     par = W_CacheLumpName("WIPAR", PU_STATIC);   
  1679.  
  1680.     // "killers" (vertical)
  1681.     killers = W_CacheLumpName("WIKILRS", PU_STATIC);
  1682.  
  1683.     // "victims" (horiz)
  1684.     victims = W_CacheLumpName("WIVCTMS", PU_STATIC);
  1685.  
  1686.     // "total"
  1687.     total = W_CacheLumpName("WIMSTT", PU_STATIC);   
  1688.  
  1689.     // your face
  1690.     star = W_CacheLumpName("STFST01", PU_STATIC);
  1691.  
  1692.     // dead face
  1693.     bstar = W_CacheLumpName("STFDEAD0", PU_STATIC);    
  1694.  
  1695.     for (i=0 ; i<MAXPLAYERS ; i++)
  1696.     {
  1697.     // "1,2,3,4"
  1698.     sprintf(name, "STPB%d", i);      
  1699.     p[i] = W_CacheLumpName(name, PU_STATIC);
  1700.  
  1701.     // "1,2,3,4"
  1702.     sprintf(name, "WIBP%d", i+1);     
  1703.     bp[i] = W_CacheLumpName(name, PU_STATIC);
  1704.     }
  1705.  
  1706. }
  1707.  
  1708. void WI_unloadData(void)
  1709. {
  1710.     int        i;
  1711.     int        j;
  1712.  
  1713.     Z_ChangeTag(wiminus, PU_CACHE);
  1714.  
  1715.     for (i=0 ; i<10 ; i++)
  1716.     Z_ChangeTag(num[i], PU_CACHE);
  1717.     
  1718.     if (gamemode == commercial)
  1719.     {
  1720.       for (i=0 ; i<NUMCMAPS ; i++)
  1721.         Z_ChangeTag(lnames[i], PU_CACHE);
  1722.     }
  1723.     else
  1724.     {
  1725.     Z_ChangeTag(yah[0], PU_CACHE);
  1726.     Z_ChangeTag(yah[1], PU_CACHE);
  1727.  
  1728.     Z_ChangeTag(splat, PU_CACHE);
  1729.  
  1730.     for (i=0 ; i<NUMMAPS ; i++)
  1731.         Z_ChangeTag(lnames[i], PU_CACHE);
  1732.     
  1733.     if (wbs->epsd < 3)
  1734.     {
  1735.         for (j=0;j<NUMANIMS[wbs->epsd];j++)
  1736.         {
  1737.         if (wbs->epsd != 1 || j != 8)
  1738.             for (i=0;i<anims[wbs->epsd][j].nanims;i++)
  1739.             Z_ChangeTag(anims[wbs->epsd][j].p[i], PU_CACHE);
  1740.         }
  1741.     }
  1742.     }
  1743.     
  1744.     Z_Free(lnames);
  1745.  
  1746.     Z_ChangeTag(percent, PU_CACHE);
  1747.     Z_ChangeTag(colon, PU_CACHE);
  1748.     Z_ChangeTag(finished, PU_CACHE);
  1749.     Z_ChangeTag(entering, PU_CACHE);
  1750.     Z_ChangeTag(kills, PU_CACHE);
  1751.     Z_ChangeTag(secret, PU_CACHE);
  1752.     Z_ChangeTag(sp_secret, PU_CACHE);
  1753.     Z_ChangeTag(items, PU_CACHE);
  1754.     Z_ChangeTag(frags, PU_CACHE);
  1755.     Z_ChangeTag(time, PU_CACHE);
  1756.     Z_ChangeTag(sucks, PU_CACHE);
  1757.     Z_ChangeTag(par, PU_CACHE);
  1758.  
  1759.     Z_ChangeTag(victims, PU_CACHE);
  1760.     Z_ChangeTag(killers, PU_CACHE);
  1761.     Z_ChangeTag(total, PU_CACHE);
  1762.     //  Z_ChangeTag(star, PU_CACHE);
  1763.     //  Z_ChangeTag(bstar, PU_CACHE);
  1764.     
  1765.     for (i=0 ; i<MAXPLAYERS ; i++)
  1766.     Z_ChangeTag(p[i], PU_CACHE);
  1767.  
  1768.     for (i=0 ; i<MAXPLAYERS ; i++)
  1769.     Z_ChangeTag(bp[i], PU_CACHE);
  1770. }
  1771.  
  1772. void WI_Drawer (void)
  1773. {
  1774.     switch (state)
  1775.     {
  1776.       case StatCount:
  1777.     if (deathmatch)
  1778.         WI_drawDeathmatchStats();
  1779.     else if (netgame)
  1780.         WI_drawNetgameStats();
  1781.     else
  1782.         WI_drawStats();
  1783.     break;
  1784.     
  1785.       case ShowNextLoc:
  1786.     WI_drawShowNextLoc();
  1787.     break;
  1788.     
  1789.       case NoState:
  1790.     WI_drawNoState();
  1791.     break;
  1792.     }
  1793. }
  1794.  
  1795.  
  1796. void WI_initVariables(wbstartstruct_t* wbstartstruct)
  1797. {
  1798.  
  1799.     wbs = wbstartstruct;
  1800.  
  1801. #ifdef RANGECHECKING
  1802.     if (gamemode != commercial)
  1803.     {
  1804.       if ( gamemode == retail )
  1805.     RNGCHECK(wbs->epsd, 0, 3);
  1806.       else
  1807.     RNGCHECK(wbs->epsd, 0, 2);
  1808.     }
  1809.     else
  1810.     {
  1811.     RNGCHECK(wbs->last, 0, 8);
  1812.     RNGCHECK(wbs->next, 0, 8);
  1813.     }
  1814.     RNGCHECK(wbs->pnum, 0, MAXPLAYERS);
  1815.     RNGCHECK(wbs->pnum, 0, MAXPLAYERS);
  1816. #endif
  1817.  
  1818.     acceleratestage = 0;
  1819.     cnt = bcnt = 0;
  1820.     firstrefresh = 1;
  1821.     me = wbs->pnum;
  1822.     plrs = wbs->plyr;
  1823.  
  1824.     if (!wbs->maxkills)
  1825.     wbs->maxkills = 1;
  1826.  
  1827.     if (!wbs->maxitems)
  1828.     wbs->maxitems = 1;
  1829.  
  1830.     if (!wbs->maxsecret)
  1831.     wbs->maxsecret = 1;
  1832.  
  1833.     if ( gamemode != retail )
  1834.       if (wbs->epsd > 2)
  1835.     wbs->epsd -= 3;
  1836. }
  1837.  
  1838. void WI_Start(wbstartstruct_t* wbstartstruct)
  1839. {
  1840.  
  1841.     WI_initVariables(wbstartstruct);
  1842.     WI_loadData();
  1843.  
  1844.     if (deathmatch)
  1845.     WI_initDeathmatchStats();
  1846.     else if (netgame)
  1847.     WI_initNetgameStats();
  1848.     else
  1849.     WI_initStats();
  1850. }
  1851.